<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        //***1 js中实现继承的三种方式第一种：对象冒充继承；核心使用call以对象冒充的形式调用父类的构造函数，相当于是复制父类的实例属性传递给子类
        function People(a, b) {
            this.name = a
            this.age = b
            this.run = function () {
                console.log('我在跑步....')
            }
        }
        People.prototype.sex = 'male'
        People.prototype.show = function () {
            console.log('我是：' + this.name + "我：" + this.age)
        }
        var peo = new People('傻逼',15)

        function Student(c,d){
            People.call(this,c,d)  //此处People中的this表示将来所创建的Student对象，所以称为对象冒充
        }
        var stu = new Student('学生1',55)
        console.log(stu);
        stu.run();
        //缺点是无法继承父类原型中的属性和方法，只能继承父类构造函数的实例属性和方法

        //***2 原型链继承；核心使用prototype，将父类的实例以及原型都作为子类的原型进行传递
            function Student(c,d){}
            Student.prototype=new People()
            var stu=new Student('周杰伦',15)
           stu.run();
            stu.show();
            console.log(stu.sex);
        //缺点是无法向父类构造函数传参数，导致继承的父类属性没有值


        //***3  将以上两种方法组合继承（对象冒充+原型链）

        function Student(x,y){
            People.call(this,x,y) //----对象冒充来继承父类构造函数中的属性和方法
        }
        Student.prototype=People.prototype
  //--此处Student.protype继承new People（）的实例属性和原型属性时与函数内的对象冒充方法重复继承了对象的实例属性和方法，实例属性的优先级大于原型属性因此不会影响后续Student对象的创建，但是消耗性能
   //因此可以直接将  Student.protype=People.prototype      
        var stu=new Student('高伟杰',21)  
        console.log(stu.sex);
        stu.show();
    </script>
</head>

<body>

</body>

</html>